#include "xencode.h"
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/log.h>
#include <libavutil/opt.h>
}
AVPacket *XEncode::Encode(const AVFrame *frame, int *errNo) {
  if (errNo)
    *errNo = 0;
  if (!frame)
    return nullptr;
  std::unique_lock<std::mutex> lock(mux_);
  if (!c_)
    return nullptr;
  AVPacket *pkt = nullptr;
  pkt = av_packet_alloc();
  if (!pkt) {
    return nullptr;
  }
  auto re = avcodec_send_frame(c_, frame);
  if (re != 0) {
    if (errNo)
      *errNo = re;
    PrintErr(re);
    av_packet_free(&pkt);
    return nullptr;
  }
  re = avcodec_receive_packet(c_, pkt);
  if (re == 0) {
    return pkt;
  }
  av_packet_free(&pkt);
  if (errNo)
    *errNo = re;
  if (re == AVERROR(EAGAIN) || AVERROR_EOF) {
    return nullptr;
  }
  if (re < 0) {
    PrintErr(re);
    return nullptr;
  }
  return nullptr;
}
std::vector<AVPacket *> XEncode::End() {
  std::vector<AVPacket *> res;
  std::unique_lock<std::mutex> lock(mux_);
  if (!c_)
    return res;
  auto re = avcodec_send_frame(c_, nullptr);
  if (re != 0) {
    PrintErr(re);
    return res;
  }
  while (re >= 0) {
    AVPacket *pkt = nullptr;
    pkt = av_packet_alloc();
    re = avcodec_receive_packet(c_, pkt);
    if (re != 0) {
      av_packet_free(&pkt);
      break;
    }
    res.push_back(pkt);
  }
  return res;
}

